package com.lzx.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lzx.shop.dao.OrderDao;
import com.lzx.shop.dataobject.OrderDO;
import com.lzx.shop.dataobject.ProductDO;
import com.lzx.shop.dataobject.ProductDetailDO;
import com.lzx.shop.dataobject.UserDO;
import com.lzx.shop.enums.OrderStatus;
import com.lzx.shop.model.ProductDetail;
import com.lzx.shop.model.Result;
import com.lzx.shop.service.OrderService;
import com.lzx.shop.service.ProductDetailService;
import com.lzx.shop.service.ProductService;
import com.lzx.shop.utils.ResultUtil;
import com.lzx.shop.utils.UUIDUtil;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.core.Local;
import org.springframework.data.domain.Sort.Order;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author 刘正星
 * @version 1.0.0
 * @ClassName OrderServcieImpl.java
 * @Description TODO
 * @createTime 2021年03月21日 15:35:00
 */
@Service
public class OrderServcieImpl implements OrderService {

    public static final Logger LOG =  LoggerFactory.getLogger(OrderServcieImpl.class);


    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private ProductDetailService productDetailService;

    @Autowired
    private ProductService productService;

    @Autowired
    private OrderDao orderDao;

    @Override
    public OrderDO save(OrderDO object) {

        object.setGmtModified(LocalDateTime.now());
        if (StringUtils.isBlank(object.getId())){
            object.setId(UUIDUtil.getUUID());
            object.setGmtCreated(LocalDateTime.now());
            object.setOrderNumber(getAutoId());
            return orderDao.insert(object) > 0 ? object : null;
        }
        return orderDao.updateById(object) > 0 ? object : null;

    }

    @Override
    public List<OrderDO> findAll() {
        return orderDao.selectList(null);
    }

    @Override
    public OrderDO findById(String id) {
        return orderDao.selectById(id);
    }

    @Override
    public boolean update(OrderDO object) {
        return orderDao.updateById(object)>0;
    }

    @Override
    public boolean DeleteById(String id) {
        return orderDao.deleteById(id)>0;
    }

    @Override
    public List<OrderDO> findByUserId(String userId) {

        Map<String,Object> queryMap = new HashMap<>();
        queryMap.put("user_id",userId);
        List<OrderDO> orderDOS = orderDao.selectByMap(queryMap);
        return orderDOS;
    }

    @Override
    public List<OrderDO> findAllNeed() {
        return orderDao.findAllNeed();
    }

    @Override
    public OrderDO findByOrderNumber(String orderNumber) {
        if (StringUtils.isBlank(orderNumber)){
            return null;
        }
        QueryWrapper<OrderDO> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(OrderDO::getOrderNumber,orderNumber);
        return orderDao.selectOne(wrapper);
    }

    @Override
    public OrderDO updateOrderStatus(String orderNum, OrderStatus tradePaidSuccess) {
        if (StringUtils.isBlank(orderNum)||StringUtils.isBlank(tradePaidSuccess.toString())){
            return null;
        }
        OrderDO orderDO = findByOrderNumber(orderNum);
        if (orderDO==null){
            return null;
        }
        orderDO.setStatus(tradePaidSuccess.toString());
       int result = orderDao.updateById(orderDO);
        return result > 0 ? orderDO : null;
    }

    @Override
    public OrderDO updateProductPersonNumber(String orderNumber) {
        if (StringUtils.isEmpty(orderNumber)){
            return null;
        }
        OrderDO orderDO = findByOrderNumber(orderNumber);
        if (orderDO == null){
            return null;
        }
        //获取分布式锁
        RLock transferLock = redissonClient.getLock("PURCHASE");
        transferLock.lock();
        try {
            ProductDetailDO productDetail = productDetailService.findById(orderDO.getProductId());
            if (productDetail == null){
                return null;
            }
            //库存-1
            productDetail.setStock(productDetail.getStock()-1);
            productDetailService.save(productDetail);
            ProductDO product = productService.findById(productDetail.getProductId());
            if (product == null){
                return null;
            }
            //购买人数+1
            product.setPerchaseNum(product.getPerchaseNum()+1);
            productService.save(product,null);
        }catch (Exception e){
            LOG.error("e is"+ e);
        }finally {
            transferLock.unlock();
        }
        return orderDO;
    }


    public Result updateProduct(String productId, int num){

        System.out.println(" updateProduct");

        //获取分布式锁
        RLock transferLock = redissonClient.getLock("PURCHASE");
        transferLock.lock();
        try {
            ProductDetailDO productDetail = productDetailService.findByProductId(productId);
            if (productDetail == null){
                return ResultUtil.paramError();
            }
            //库存-1
            if (productDetail.getStock()<=0||productDetail.getStock()-num<0){
                return ResultUtil.customResultParam(false,"0","库存不足",false);
            }
            System.out.println("库存呀：：："+productDetail.getStock());
            productDetail.setStock(productDetail.getStock()-num);
            productDetailService.save(productDetail);
            ProductDO product = productService.findById(productDetail.getProductId());
            System.out.println(product.toString());
            if (product == null){
                return ResultUtil.paramError();
            }
            //购买人数+1
            product.setPerchaseNum(product.getPerchaseNum()+1);
            boolean result =  productService.update(product);

            System.out.println(result);


        }catch (Exception e){
            LOG.error("e is"+ e);
        }finally {
            transferLock.unlock();
        }
        return ResultUtil.success(true);
    }


    /**
     * 生成订单号
     * @return
     */
    public String getAutoId() {

        //格式化格式为年月日
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        //获取当前时间
        String now = LocalDate.now().format(dateTimeFormatter);
        //通过redis的自增获取序号
        RAtomicLong atomicLong = redissonClient.getAtomicLong(now);
        atomicLong.expire(1, TimeUnit.DAYS);
        //拼装订单号
        return now + "" + atomicLong.incrementAndGet();

    }
}
